package bestTeam.WalkieDoggie.client.Composites;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;

import bestTeam.WalkieDoggie.client.Gender;
import bestTeam.WalkieDoggie.client.Location;
import bestTeam.WalkieDoggie.client.WalkieDoggie;
import bestTeam.WalkieDoggie.client.dateComperator;
import bestTeam.WalkieDoggie.client.timeFrameComperator;
import bestTeam.WalkieDoggie.client.volunteerComperator;
import bestTeam.WalkieDoggie.client.walkieStatus;
import bestTeam.WalkieDoggie.client.Serializables.UserProfileData;
import bestTeam.WalkieDoggie.client.Serializables.UserRequest;

import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.maps.client.InfoWindowContent;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.Maps;
import com.google.gwt.maps.client.control.LargeMapControl;
import com.google.gwt.maps.client.event.MarkerClickHandler;
import com.google.gwt.maps.client.event.MarkerClickHandler.MarkerClickEvent;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.maps.client.overlay.MarkerOptions;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.MenuItem;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.StackLayoutPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.StackPanel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Widget;

public class homeComp extends Composite{


	private ArrayList<UserRequest> requests = new ArrayList<UserRequest>();

	private boolean dateSortPressed=true;
	private boolean timeSortPressed=false;
	private boolean volSortPressed=false;

	private dateComperator date_comperator_asc=new dateComperator(1);
	private dateComperator date_comperator_desc=new dateComperator(-1);

	private timeFrameComperator time_comperator_asc = new timeFrameComperator(1);
	private timeFrameComperator time_comperator_desc = new timeFrameComperator(-1);

	private volunteerComperator vol_comperator_asc = new volunteerComperator(1);
	private volunteerComperator vol_comperator_desc = new volunteerComperator(-1);

	private TabPanel tabPanel;
	private StackPanel stackWalkiesList;
	private SimplePanel simplePanel;

	private MenuBar menuBar;
	private VerticalPanel verticalPanel;
	private MenuItem mntmDate;
	private MenuItem mntmTimeFrame;
	private MenuItem mntmVolunteers;

	private VerticalPanel ver;

	private Label title;
	private Label emptyLabel;
	//private MenuItem mntmUsername;

	//map things
	private MapWidget map = null;

	public homeComp(HashMap<UserRequest,UserProfileData> requestsMap){		

		ver = new VerticalPanel();
		ver.setSpacing(5);
		initWidget(ver);
		ver.setWidth("100%");

		ver.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
		title = new Label("Ongoing Walkies:");
		title.setStyleName("titleForView");

		Label exp = new Label("\tshow Walkies of other users that might be relevant to you");

		HorizontalPanel hor = new HorizontalPanel();
		hor.add(title);

		hor.add(exp);
		//hor.setCellVerticalAlignment(exp, HasVerticalAlignment.ALIGN_TOP);

		ver.add(hor);
		ver.setSpacing(5);
		tabPanel = new TabPanel();

		ver.add(tabPanel);
		tabPanel.setSize("100%", "100%");
		
	
		verticalPanel = new VerticalPanel();
		tabPanel.add(verticalPanel, "List of Walkies", false);
		verticalPanel.setSize("100%", "100%");

		menuBar = new MenuBar(false);
		verticalPanel.add(menuBar);
		menuBar.setWidth("100%");

		mntmDate = new MenuItem("Date", false, new Command() {
			public void execute() {
				if(dateSortPressed){
					displayWalkiesListSorted(date_comperator_asc);
					dateSortPressed=false;

				}
				else{
					displayWalkiesListSorted(date_comperator_desc);
					dateSortPressed=true;

				}
			}
		});
		menuBar.addItem(mntmDate);
		mntmDate.setWidth("150px");

		mntmTimeFrame = new MenuItem("Time Frame", false, new Command() {
			public void execute() {
				if(timeSortPressed){
					displayWalkiesListSorted(time_comperator_asc);
					timeSortPressed=false;
				}
				else{
					displayWalkiesListSorted(time_comperator_desc);
					timeSortPressed=true;

				}
			}
		});
		menuBar.addItem(mntmTimeFrame);
		mntmTimeFrame.setWidth("100px");
		//			
		//			mntmUsername = new MenuItem("Username", false, new Command() {
		//				public void execute() {
		//				}
		//			});
		//			menuBar.addItem(mntmUsername);
		//			mntmUsername.setWidth("100px");
		//			
		mntmVolunteers = new MenuItem("# Volunteers", false, new Command() {
			public void execute() {
				if(volSortPressed){
					displayWalkiesListSorted(vol_comperator_asc);
					volSortPressed=false;
				}
				else{
					displayWalkiesListSorted(vol_comperator_desc);
					volSortPressed=true;

				}
			}
		});

		menuBar.addItem(mntmVolunteers);
		mntmVolunteers.setWidth("100px");


		int a = mntmVolunteers.getAbsoluteLeft();

		stackWalkiesList = new StackPanel();
		verticalPanel.add(stackWalkiesList);
		//stackWalkiesList.setSize("100%", "100%");
		
		//stackWalkiesList.set
		stackWalkiesList.addHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				int id = stackWalkiesList.getSelectedIndex();
				RequestOfFriend selectedRequest = (RequestOfFriend) stackWalkiesList.getWidget(id);
				selectedRequest.checkResizeOfMap();
			}
		}, ClickEvent.getType());


		emptyLabel = new Label("");
		//if(!WalkieDoggie.loginInfo.isNewUser())
		loadWalkiesList();

		verticalPanel.add(emptyLabel);

		/*		SimplePanel dock = new SimplePanel();
		tabPanel.add(dock, "Map of Walkies", false);
		dock.setSize("1000px", "500px");
		loadMap(dock);

		tabPanel.selectTab(0);


	}
		 */

		DockLayoutPanel dock = new DockLayoutPanel(Unit.PX);
		tabPanel.add(dock, "Map of Walkies", false);
		dock.setSize("80%", "500px");
		tabPanel.addSelectionHandler(new SelectionHandler<Integer>(){
			public void onSelection(SelectionEvent<Integer> event){
				int tabId = event.getSelectedItem();
				if(tabId==1)
					map.checkResizeAndCenter();
			}
		});
		loadMap(dock);

		tabPanel.selectTab(0);


	}

	private ArrayList<UserRequest> getRelevantOthersRequests(UserRequest[] requestsArray) {
		final ArrayList<UserRequest> res = new ArrayList<UserRequest>();

		for (final UserRequest userRequest : requestsArray) {

			UserProfileData reqUser = WalkieDoggie.requestsOwnersMap.get(userRequest);
			if(userRequest.getDate().after(new Date()) &&
					!userRequest.getCreatedBy().equals(WalkieDoggie.loginInfo.getUserData().getId()) &&
					goodTogether(WalkieDoggie.loginInfo.isNewUser(), reqUser, WalkieDoggie.loginInfo.getUserData()))
				res.add(userRequest);

		}

		return res;
	}

	private boolean goodTogether(boolean isNewUser, UserProfileData reqUser, UserProfileData user) {

		if(isNewUser)
			return true;

		if(user.getDogGender().equals(Gender.Male) && reqUser.getDogGender().equals(Gender.Male))
			if(user.getOKwithMales() && reqUser.getOKwithMales())
				return true;

		if(user.getDogGender().equals(Gender.Male) && reqUser.getDogGender().equals(Gender.Female))
			if(user.getOKwithFemales() && reqUser.getOKwithMales())
				return true;

		if(user.getDogGender().equals(Gender.Female) && reqUser.getDogGender().equals(Gender.Male))
			if(user.getOKwithMales() && reqUser.getOKwithFemales())
				return true;

		if(user.getDogGender().equals(Gender.Female) && reqUser.getDogGender().equals(Gender.Female))
			if(user.getOKwithFemales() && reqUser.getOKwithFemales())
				return true;

		return false;
	}


	//	private void loadMap(final SimplePanel dock) {
	//		/*
	//		    * Asynchronously loads the Maps API.
	//		    *
	//		    * The first parameter should be a valid Maps API Key to deploy this
	//		    * application on a public server, but a blank key will work for an
	//		    * application served from localhost.
	//		   */
	//		   Maps.loadMapsApi("AIzaSyA6APFS4_eVtj7UXM_oplwHLRtUOtPmvVE", "2", false, new Runnable() {
	//		      public void run() {
	//		        buildUi(dock);
	//		      }
	//		    });
	//
	//	}


	private void loadMap(final DockLayoutPanel dock) {
		/*
		 * Asynchronously loads the Maps API.
		 *
		 * The first parameter should be a valid Maps API Key to deploy this
		 * application on a public server, but a blank key will work for an
		 * application served from localhost.
		 */
		Maps.loadMapsApi("AIzaSyA6APFS4_eVtj7UXM_oplwHLRtUOtPmvVE", "2", false, new Runnable() {
			public void run() {
				buildUi(dock);
			}
		});

	}



	public void loadWalkiesList() {

		if(WalkieDoggie.requestsOwnersMap!=null){
			UserRequest[] tmp = (UserRequest[])WalkieDoggie.requestsOwnersMap.keySet().toArray(new UserRequest[0]);
			requests = getRelevantOthersRequests(tmp);
		}

		displayWalkiesList();


		if(!isThereSomethingToShow(requests))
			emptyLabel.setText("no items to show");
		else
			emptyLabel.setText("");

	}

	private boolean isThereSomethingToShow(ArrayList<UserRequest> requests) {

		for (UserRequest userRequest : requests) {
			if(!userRequest.getCreatedBy().equals(WalkieDoggie.loginInfo.getUserData().getId()))
				return true;
		}

		return false;
	}


	public void displayWalkiesList() {
		displayWalkiesListSorted(new dateComperator(1));

	}
	private void displayRequestOfFriend(UserRequest request) {
		//request.setMessage(WalkieDoggie.fmt.format(request.getDate())+"\t"+request.getTimeFrame()+"\t"+request.getVolunteers().length);
		//stackWalkiesList.add(new RequestOfFriend(request),request.getMessage());

		String header = "<table>"+
				"<tr width=\"1000\">"+
				"<td width=\"175px\">"+WalkieDoggie.fmt.format(request.getDate())+"</td>"+
				"<td width=\"175px\">"+request.getTimeFrame()+"</td>"+
				"<td width=\"175px\">"+request.getVolunteers().length+"</td>"+
				"</tr>"+
				"</table>"; 
		stackWalkiesList.add(new RequestOfFriend(request,true),header,true);
	}

	public TabPanel getTabPanel(){
		return this.tabPanel;
	}

	@SuppressWarnings("unchecked")
	private void displayWalkiesListSorted(Comparator<UserRequest> dc) {
		stackWalkiesList.clear();
		UserRequest[] sorted = (UserRequest[])requests.toArray(new UserRequest[0]); 
		Arrays.sort(sorted, dc);

		for (UserRequest request: sorted) {

			if( request.getStatus().equals(walkieStatus.NEW) &&
					!request.getCreatedBy().equals(WalkieDoggie.loginInfo.getUserData().getId()))


				displayRequestOfFriend(request);
		}
	}


	private void buildUi(DockLayoutPanel dock) {
		// Open a map centered on Cawker City, KS USA
		Location l = WalkieDoggie.loginInfo.getUserData().getGeoLocation();

		LatLng loc = null;
		boolean isValidAdress = false;

		if(l==null){
			loc = LatLng.newInstance(32.1141185, 34.7960162);
		} else {
			loc = LatLng.newInstance(l.getLat(), l.getLng());
			isValidAdress = true;
		}

		String str =  "your house";

		map = new MapWidget(loc, 16);
		map.setSize("100%", "100%");
		// Add some controls for the zoom level
		map.addControl(new LargeMapControl());

		if (isValidAdress){
			// Add a marker
			MarkerOptions mo = MarkerOptions.newInstance();
			mo.setTitle(str);
			map.addOverlay(new Marker(loc,mo));


			// Add an info window to highlight a point of interest

			//			map.getInfoWindow().open(map.getCenter(),
			//					new InfoWindowContent(str));
		}


		dock.addNorth(map, 500);

		addMarkersOnMap();
	}


	private void addMarkersOnMap() {
		for (UserRequest userRequest : requests) {
			UserProfileData user = WalkieDoggie.requestsOwnersMap.get(userRequest);

			if ((user!=null)&&(userRequest.getStatus()==walkieStatus.NEW)){

				MarkerOptions mo = MarkerOptions.newInstance();
				String str = ""+userRequest.getUserName()+": "+WalkieDoggie.fmt.format(userRequest.getDate())+" - "+userRequest.getTimeFrame();
				mo.setTitle(str);
				mo.setClickable(true);
				LatLng location = LatLng.newInstance(user.getGeoLocation().getLat(), user.getGeoLocation().getLng());
				Marker marker = new Marker(location,mo);
				marker.addMarkerClickHandler(generateClickHandler(userRequest));
				map.addOverlay(marker);
			}
		}

	}

	private MarkerClickHandler generateClickHandler(final UserRequest ur){
		MarkerClickHandler m = new MarkerClickHandler() {

			@Override
			public void onClick(MarkerClickEvent event) {
				boolean isVolunteered=false;
				for (int i =0;i<ur.getVolunteers().length;i++){

					if (ur.getVolunteers()[i].equals(WalkieDoggie.loginInfo.getUserData().getId()))
						isVolunteered = true;
				}

				// TODO Auto-generated method stub
				userProfileComp baseComp = new userProfileComp(WalkieDoggie.requestsOwnersMap.get(ur),true);
				final PopupPanel userComp = new PopupPanel(true);
				VerticalPanel vr = baseComp.getVerticalPanel();
				Label label1 = new Label("Date: "+WalkieDoggie.fmt.format(ur.getDate()));
				Label label2 = new Label("Time Frame: " + ur.getTimeFrame());
				HorizontalPanel hp1 = new HorizontalPanel();
				HorizontalPanel hp2 = new HorizontalPanel();
				hp1.add(label1);
				hp2.add(label2);
				hp1.setSpacing(5);
				hp2.setSpacing(5);
				vr.add(hp1);
				vr.add(hp2);

				Button confirmButton = new Button();



				if(isVolunteered){
					confirmButton.setText("UnVolunteer");			
				}
				else{
					confirmButton.setText("Volunteer");		

				}

				final boolean finalbool = isVolunteered;

				confirmButton.addClickHandler(new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {

						if(WalkieDoggie.loginInfo.isNewUser()){
							WalkieDoggie.mainPanel.clear();
							WalkieDoggie.mainPanel.add(WalkieDoggie.profile_comp);
						}
						else if(!finalbool){
							RequestOfFriend rof = new RequestOfFriend(ur,true);
							rof.confirmRequest(ur);
							userComp.hide(true);

						}
						else{
							RequestOfFriend rof = new RequestOfFriend(ur,true);
							rof.UNconfirmRequest(ur);
							userComp.hide(true);
						}
					}

				});

				vr.add(confirmButton);

				userComp.setWidget(vr);
				userComp.setPopupPosition(WalkieDoggie.header_comp.getAbsoluteLeft()+300, WalkieDoggie.header_comp.getAbsoluteTop()+200);
				userComp.setGlassEnabled(true);
				userComp.show();

				//displayWalkiesList();
			}
		};
		return m;
	}

}
